#include <iostream>
#include <memory>

class Fruit {
public:
    virtual void name() = 0;
};

class Apple : public Fruit {
public:
    virtual void name() override {
        std::cout << "apple\n";
    }
};

class Banana : public Fruit {
public:
    virtual void name() override {
        std::cout << "banana\n";
    }       
};

class FruitFactory {
public:
    virtual std::shared_ptr<Fruit> create() = 0; 
};

class AppleFactory : public FruitFactory {
public:
    virtual std::shared_ptr<Fruit> create() override {
        return std::make_shared<Apple>();
    }
};

class BananaFactory : public FruitFactory {
public:
    virtual std::shared_ptr<Fruit> create() override {
        return std::make_shared<Banana>();
    }
};

int main() {
    std::shared_ptr<FruitFactory> fruit_factory(new AppleFactory);
    std::shared_ptr<Fruit> fruit = fruit_factory->create();
    fruit->name();
    
    fruit_factory.reset(new BananaFactory);
    fruit = fruit_factory->create();
    fruit->name();
    return 0;
}
